package blog.spring.db.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import blog.core.exception.FormParamErrorException;
import blog.core.exception.NotFoundException;
import blog.core.util.Conditions;
import blog.core.util.ExceptionUtils;
import blog.core.util.ServiceUtils;
import blog.core.util.ThreadUtils;
import blog.spring.db.dao.IArticleDAO;
import blog.spring.db.dao.ICommentDAO;
import blog.spring.db.entity.ArticleContent;
import blog.spring.db.entity.ArticleInfo;
import blog.spring.db.entity.Comment;
import blog.spring.db.service.IArticleService;
import blog.spring.db.service.IGlobalService;
import blog.spring.db.service.ITypeService;

@Service("articleService")
public class ArticleService extends BaseService<ArticleInfo> implements
		IArticleService {

	private final IArticleDAO articleDao;
	@Resource
	private ITypeService typeService;
	@Resource
	private ICommentDAO commentDao;
	@Resource
	private IGlobalService globalService;
	public static final String TYPE_NAME = "文章";

	@Autowired
	public ArticleService(IArticleDAO articleDao) {
		super(articleDao, TYPE_NAME);
		this.articleDao = articleDao;
	}

	@Override
	public void save(ArticleInfo entity) throws FormParamErrorException {
		articleExceprion(entity);
		breviaryArticle(entity);
		entity.setCreateDate(new Date());
		super.save(entity);
		globalService.updateArticleCount();
	}

	@Override
	public void update(ArticleInfo entity) throws FormParamErrorException,
			NotFoundException {
		articleExceprion(entity);
		ArticleInfo ptInfo = findById(entity.getArticleId());
		if (ptInfo == null)
			ExceptionUtils.NewNotFound(entity.getArticleId(), TYPE_NAME);
		// 修改持久化对象中指定的属性
		ptInfo.setTitle(entity.getTitle());// 标题
		ptInfo.getArticleContent().setContent(// 内容
				entity.getArticleContent().getContent());
		breviaryArticle(ptInfo);
		// 更新时间
		ptInfo.setUpdateDate((new Date()));
		super.update(ptInfo);
	}

	@Override
	public ArticleInfo findById(int id) throws NotFoundException {
		ArticleInfo info = super.findById(id);
		// 异步更新点击数
		ThreadUtils.New(new NewThread(articleDao, id));
		return info;
	}

	@Override
	public void remove(ArticleInfo entity) {
		super.remove(entity);
		globalService.updateArticleCount();
	}

	@Override
	public void addTo(int id, String addContent)
			throws FormParamErrorException, NotFoundException {
		ArticleInfo info = findById(id);
		ArticleContent content = info.getArticleContent();
		content.setContent(content.getContent() + addContent);
		update(info);
	}

	/**
	 * 操作Article数据需要判断的异常方法
	 *
	 * @param article
	 *            文章对象
	 * @throws FormParamErrorExceptio
	 */
	private void articleExceprion(ArticleInfo article)
			throws FormParamErrorException {
		if (article.getArticleContent() == null
				|| article.getArticleContent().getContent() == null)
			throw new FormParamErrorException("文章内容不能为空");
		if (article.getArticleContent().getContent().length() <= 35)
			throw new FormParamErrorException("文章内容不得少于35字");
	}

	/**
	 * 设置文章摘要信息
	 *
	 * @param article
	 *            需要设置的文章对象
	 */
	private void breviaryArticle(ArticleInfo article) {
		// 设置文章摘要
		String content = article.getArticleContent().getContent();
		String breviaryCotent = ServiceUtils.filterHtml(content);
		if (breviaryCotent.length() <= 255)
			article.setBeviaryContent(breviaryCotent);
		else
			article.setBeviaryContent(breviaryCotent.substring(0, 255));
	}

	@Override
	public List<ArticleInfo> findTopAll() {
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("isTop", true);
		return articleDao.searchList(conditions, null, null, "createDate",
				"desc", false);
	}

	@Override
	public List<ArticleInfo> indexList(int pagNum) {
		List<ArticleInfo> indexList = new ArrayList<ArticleInfo>();
		List<ArticleInfo> topList = findTopAll();
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("isTop", false);
		List<ArticleInfo> pageList = searchList(conditions, pagNum, 15,
				"createDate", "desc", false);
		if (topList != null)
			indexList.addAll(topList);
		if (pageList != null)
			indexList.addAll(pageList);
		return indexList;
	}

	@Override
	public void updateCommentCount(int id) {
		String hql = "select count(t) from Comment t where t.articleInfo.articleId = "
				+ id;
		int count = ((Number) commentDao.getCurrentSession().createQuery(hql)
				.uniqueResult()).intValue();
		findById(id).setCommentCount(count);
	}

	@Override
	public List<ArticleInfo> findHot(int count) {
		return findList(1, count, "commentCount", "desc");
	}

	private class NewThread implements Runnable {
		private IArticleDAO articleDao;
		private int id;

		public NewThread(IArticleDAO articleDao, int id) {
			super();
			this.articleDao = articleDao;
			this.id = id;
		}

		@Override
		public void run() {
			ArticleInfo info = articleDao.selectById(id);
			info.getArticleContent().setHits(
					info.getArticleContent().getHits() + 1);
			articleDao.update(info);
		}

	}

	@Override
	public List<Comment> getComments(int id) {
		Conditions cd = new Conditions();
		cd.put("articleInfo.articleId", id);
		return commentDao.searchList(cd, null, null, "createDate", "desc",
				false);
	}
}
